home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Development Kits / MPW etc / MPW-GM / MPW / Examples / HyperXExamples / PExamples / LittleDialog.p next >
Encoding:
Text File  |  1998-12-03  |  5.2 KB  |  190 lines  |  [TEXT/MPS ]

  1. (*
  2.  
  3.     © 1988,1992 by Apple Computer, Inc.
  4.     All Rights Reserved
  5.  
  6.     LittleDialog -- a Hypercard XCMD that displays a modal dialog. This example uses
  7.     callbacks to HyperCard provided by the HyperXLib.o library, introduced with MPW 3.0.
  8.     The library provides a consistent set of routines to call HyperCard internal routines
  9.     from any language. This is the first public demonstration of its use.
  10.  
  11.     
  12.     Form: LittleDialog DisplayText
  13.     
  14.     Example: LittleDialog "Display this very long text string that wouldn't fit in Answer."
  15.     
  16.     DisplayText: The text to display in the window. Up to 255 characters may be displayed.
  17.     
  18.  
  19.     To compile and link this file using MPW Pascal, select the following lines and
  20.     press ENTER:
  21.     
  22.     make LittleDialog
  23.     
  24.     or:
  25.     
  26.     Pascal LittleDialog.p -mbg off
  27.     Link -w -rt XCMD=10002 ∂
  28.         -m ENTRYPOINT ∂
  29.         -sg LittleDialog ∂
  30.         LittleDialog.p.o ∂
  31.         "{Libraries}HyperXLib.o" ∂
  32.         "{Libraries}Interface.o" ∂
  33.         "{PLibraries}PasLib.o" ∂
  34.         -o "::HyperXExample Stack"
  35.     Rez LittleDialog.r -o "::HyperXExample Stack" -append
  36.  
  37. *)
  38.  
  39. {$R-}
  40. {$Z+}
  41.  
  42. UNIT DummyUnit;
  43.  
  44.  
  45. INTERFACE
  46.  
  47. USES
  48.     Types,
  49.     Memory,
  50.     QuickDraw,
  51.     Dialogs,
  52.     Resources,
  53.     PasLibIntf,
  54.     HyperXCmd;
  55.  
  56.  
  57. IMPLEMENTATION
  58.  
  59.  
  60. PROCEDURE LittleDialog(paramPtr: XCmdPtr);        FORWARD;
  61.  
  62. PROCEDURE ENTRYPOINT(paramPtr: XCmdPtr);
  63.   
  64.     BEGIN
  65.         LittleDialog(paramPtr);
  66.     END;
  67.  
  68.  
  69.     {*
  70.      * Draw the ring around the OK button, the way that
  71.      * alert boxes get it. This procedure is only called 
  72.      * by the Dialog Manager for update events.
  73.      *
  74. •••• NOTE: In Pascal, code referenced in an XCMD using the @ operator
  75. ••••       must reside outside of the main body of the XCMD code.
  76.      *}
  77.      
  78. PROCEDURE DrawOKDefault(theDialog: DialogPtr; theItem: INTEGER);
  79.     CONST
  80.         curveRad = 16;
  81.  
  82.     VAR
  83.         savePen:                    PenState;
  84.         tempType:                    Integer;
  85.         tempHandle:                Handle;
  86.         tempRect:                    Rect;
  87.  
  88.     BEGIN
  89.         GetPenState(savePen); {save the old pen state}
  90.         
  91.         { Draw an outline around our default button.}
  92.         
  93.         GetDIalogItem(theDialog, theItem, tempType, tempHandle, tempRect); {get the item’s rect}
  94.         PenSize(3,3); {make the pen fatter}
  95.         FrameRoundRect(tempRect,curveRad,curveRad); {draw the ring}
  96.  
  97.         SetPenState(savePen); {restore the pen state}
  98.     END; {DrawOKDefault}
  99.  
  100.  
  101. PROCEDURE LittleDialog(paramPtr: XCmdPtr);
  102.  
  103.     CONST
  104.                 dialogID = 10002;
  105.                 iDefOKRing = OK+1;        { number of user item for ring around default button }
  106.                 gap = -4;
  107.  
  108.     VAR
  109.               myDialogPtr:             DialogPtr;
  110.                 savePort:                    GrafPtr;
  111.                 itemHit:                    INTEGER;
  112.                 tempType:                    INTEGER;
  113.                 tempHandle:                Handle;
  114.                 ctlRect:                    Rect;
  115.                 displayStr:                Str255;
  116.  
  117.  
  118.     PROCEDURE ErrAbort(errMsg: Str255); {Abort execution returning an error message}
  119.         BEGIN
  120.             SetPort(savePort); {restore the port}
  121.             paramPtr^.returnValue := PasToZero(paramPtr,errMsg); {XCMDs can return values}
  122.             EXIT(LittleDialog); {leave the XCMD}
  123.         END;
  124.  
  125.  
  126.     BEGIN {Main}
  127.  
  128.         { Save the current port; good defensive programming practice.
  129.         NOTE: this port will always be the card window's grafport. }
  130.         
  131.         GetPort(savePort);
  132.         
  133.         { It is always a good idea to check for the correct number of parameters.}
  134.         { Another nice idea is to return the proper syntax of the call if it has
  135.             been called improperly.}
  136.         
  137.         IF (paramPtr^.paramCount <> 1) THEN
  138.             ErrAbort('Correct usage is: "LittleDialog fieldName"');
  139.         
  140.         { This routine will use DLOG and DITL resources that must be available.
  141.             Since XCMDs may be moved by ResEdit without knowledge of those resources,
  142.             we must check for their availability. To suggest that our DLOG, DITL, and
  143.             XCMD all belong together, we have numbered them all the same: 10002.}
  144.         
  145.         IF (GetResource('DLOG',dialogID) = NIL) OR
  146.              (GetResource('DITL',dialogID) = NIL) THEN
  147.             ErrAbort('XCMD requires resources: DLOG 10002 & DITL 10002.');
  148.  
  149.         ZeroToPas(paramPtr,paramPtr^.params[1]^,displayStr); {the string to display}
  150.         ParamText(displayStr,'','',''); {DLOG 10002 already set up for this call}
  151.         SetDialogFont(0);        { * possibly redundant, but safe nonetheless}
  152.  
  153.         myDialogPtr := GetNewDialog(dialogID,NIL,POINTER(-1)); {get ptr to invisible dialog}
  154.         IF myDialogPtr = NIL THEN
  155.             ErrAbort('Not enough memory for dialog.');
  156.  
  157.         {Move our default-OK-button userItem to around the OK button, and set its
  158.             item handle to be a pointer to our other drawing procedure}
  159.  
  160.         GetDIalogItem(myDialogPtr,OK,tempType,tempHandle,ctlRect); {get rect of OK button}
  161.         InsetRect(ctlRect,gap,gap); {make the rect a little bigger}
  162.             {set the same old type, our procptr, and the new box}
  163.         SetDialogItem(myDialogPtr,iDefOKRing,userItem+itemDisable,@DrawOKDefault,ctlRect);
  164.  
  165.         ShowWindow(myDialogPtr); {Make the dialog visible}
  166.             
  167.         { Set the cursor to the arrow for use with the dialog box.}
  168.             
  169.         InitCursor;
  170.         
  171.         { Make the modal dialog handle events. }
  172.         
  173.         FlushEvents(everyEvent,0); {flush all events to be safe}
  174.         REPEAT
  175.             ModalDialog(NIL,itemHit); {stay modal until the user clicks OK}
  176.         UNTIL itemHit = OK;
  177.         
  178.         { Let HyperCard set the cursor to a known state, so the next "idle" message
  179.             after the dialog goes away will reset it to the correct cursor. (HyperCard
  180.             doesn't know we did an InitCursor.)}
  181.             
  182.         SendHCMessage(paramPtr,'set cursor to 4');    {4 = the watch cursor}
  183.  
  184.         DisposeDialog(myDialogPtr); {get rid of dialog and dialog handle}
  185.         SetPort(savePort); {restore the port}
  186.  
  187.     END; {main}
  188.     
  189. END. {LittleDialog}
  190.